package ru.ifmo.network;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.*;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author avhaliullin
 */
public class UDPSender implements Runnable {
    private DatagramSocket socket;
    private final HelloMessageProvider provider;
    private final Logger log = Logger.getLogger(UDPSender.class.getName());
    private final int port;

    private void initSocket() {
        try {
            this.socket = new DatagramSocket();
            socket.setBroadcast(true);
        } catch (SocketException e) {
            log.log(Level.SEVERE, "Can't create socket", e);
        }
    }

    public UDPSender(HelloMessageProvider provider, int port) {
        this.provider = provider;
        this.port = port;
        initSocket();
    }


    public void run() {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(1024);
        DataOutputStream os = new DataOutputStream(new BufferedOutputStream(byteArrayOutputStream));
        try {
            HelloMessage message = provider.message();
            os.writeUTF(message.getHostAddress());
            os.writeUTF(message.getHostName());
            os.writeInt(message.getHashCode());
            os.flush();
        } catch (IOException e) {
            log.log(Level.SEVERE, "Some strange exception", e);
            return;
        }
        byte[] buf = byteArrayOutputStream.toByteArray();
        DatagramPacket packet = null;
        try {
            packet = new DatagramPacket(buf, buf.length, InetAddress.getByName("255.255.255.255"), port);
        } catch (UnknownHostException e) {
            //ignore
        }

        try {
            socket.send(packet);
        } catch (IOException e) {
            log.log(Level.WARNING, "Failed to send datagram, try to reconnect", e);
            initSocket();
        }
    }
}
